import { mapConfig } from '@/config/map'
import { messageChannel } from '@/utils/tools'

export default class TideMap {
  static PLUGINS = []

  constructor(option = {}) {
    const { plugin = [], ...opt } = option
    const defaultOptions = {
      container: 'map',
      style: 'aegis://styles/aegis/Streets-v2',
      zoom: 11,
      center: [114.36762660224, 30.574061652114],
      localIdeographFontFamily: 'Microsoft YoHei'
    }
    this.options = { ...defaultOptions, ...opt }
    this.plugins = [...TideMap.PLUGINS, ...plugin]
  }

  async init() {
    await this.mapAuthor()
    await this.loadPlugin()
    return this.createMap()
  }

  loadJS(url) {
    return new Promise((resolve, reject) => {
      const sgmapScript = document.querySelector('#sgmap')
      if (sgmapScript) {
        resolve()
      } else {
        var domScript = document.createElement('script')
        domScript.src = url
        domScript.id = 'sgmap'
        domScript.onload = domScript.onreadystatechange = function () {
          if (
            !this.readyState ||
            'loaded' === this.readyState ||
            'complete' === this.readyState
          ) {
            resolve()
            this.onload = this.onreadystatechange = null
            this.parentNode.removeChild(this)
          }
        }
        document.getElementsByTagName('head')[0].appendChild(domScript)
      }
    })
  }
  // eslint-disable-next-line class-methods-use-this
  mapAuthor() {
    return this.loadJS('https://map.sgcc.com.cn/maps?v=3.0.0').then(res => {
      return SGMap.tokenTask.login(
        '9ce13d3a827e321ebafdf3480ec7f71e',
        'be7f73842d44324f9a0f9b629b1c7516'
      )
    })
  }

  loadPlugin() {
    if (!Array.isArray(this.plugins)) return
    // eslint-disable-next-line no-undef
    const uniqPlugins = this.plugins.filter(
      i => !Object.prototype.hasOwnProperty.call(SGMap, i.split('.').pop())
    )
    if (!uniqPlugins.length) {
      // eslint-disable-next-line consistent-return
      return Promise.resolve([])
    }
    // eslint-disable-next-line no-undef,consistent-return
    return SGMap.plugin(uniqPlugins)
  }

  createMap() {
    return new Promise(reslove => {
      // eslint-disable-next-line no-undef
      this.map = new SGMap.Map(this.options)
      reslove(this.map)
    })
  }

  // 添加边界
  addBound(adcode = '湖北省') {
    this.createMask()
    return this.getFeature(adcode)
  }

  // 更新边界
  updateBound(adcode) {
    this.getFeature(adcode)
  }

  createMask() {
    // 行政区划边界线
    this.map.addLayer({
      id: 'power-line',
      type: 'line',
      source: {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: []
        }
      },
      paint: {
        'line-color': '#FFAC4D',
        'line-width': 1
      }
    })

    // 遮罩面
    this.map.addLayer({
      id: 'mask-polygon',
      type: 'fill',
      source: {
        type: 'geojson',
        data: {
          type: 'FeatureCollection',
          features: []
        }
      },
      paint: {
        'fill-color': '#061835',
        'fill-outline-color': '#061835'
      }
    })
  }

  getFeature(adcode) {
    return new Promise((reslove, reject) => {
      if (!this.map.district) {
        fetch('/json/hubei.json')
          .then(r => r.json())
          .then(result => {
            this.addLayer(adcode, result)
          })
          .catch(e => reject(e))
      } else {
        this.addLayer(adcode)
      }
    })
  }

  addLayer(adcode, result) {
    const { map } = this
    let features = []
    let district
    const featuresSymbol = []
    let featuresPolygon = []
    // 外层遮罩方形边界
    let outSideShape = [
      [
        [-180, 90],
        [180, 90],
        [180, -90],
        [-180, -90]
      ]
    ]

    const reduceFn = (pre, curr) => {
      pre.push({ ...curr })
      // eslint-disable-next-line no-unused-expressions
      curr.sub_districts &&
        curr.sub_districts.forEach(v => {
          reduceFn(pre, v)
        })
      return pre
    }

    // 主要区分直辖市和其他省份
    if (!this.map.district) {
      district = [result.data.districts[0]].reduce(reduceFn, [])
      this.map.district = district
    } else {
      district = this.map.district
    }
    if (adcode) {
      district = district.find(
        i => i.adcode === adcode || i.name.includes(adcode)
      )
      this.map.flyTo({
        // center: district.center.split(','),
        // center: [111.301861, 31.054498],
        zoom: 6.6,
        essential: true,
        ...mapConfig[adcode],
        easing(t) {
          if (t !== 1) {
            // store.commit('setToggleFilter', false);
          } else {
            messageChannel.port1.postMessage(t)
            // store.commit('setToggleFilter', true);
          }
          return t
        }
      })
    } else {
      this.map.flyTo({
        center: [111.301861, 31.054498],
        zoom: 6.6,
        essential: true,
        ...mapConfig[adcode],
        easing(t) {
          if (t !== 1) {
            // store.commit('setToggleFilter', false);
          } else {
            messageChannel.port1.postMessage(t)
            // store.commit('setToggleFilter', true);
          }
          return t
        }
      })
    }

    // 限制最大显示范围，也可以初始化地图的时候用maxZoom设置一个最大展示层级
    // eslint-disable-next-line no-restricted-syntax
    for (const o in district.sub_districts) {
      if (district.sub_districts[o].shape === undefined) {
        // eslint-disable-next-line no-continue
        continue
      }
      const { shape } = district.sub_districts[o]

      // 标注
      featuresSymbol.push({
        type: 'Feature',
        geometry: {
          coordinates: district.sub_districts[o].center.split(',').map(Number),
          type: 'Point'
        },
        properties: {
          name: district.sub_districts[o].name,
          temperature: ''
        }
      })
      // 边界
      if (shape.type === 'MultiPolygon') {
        // eslint-disable-next-line no-restricted-syntax
        for (const p in shape.coordinates) {
          if (shape.coordinates[p] instanceof Array) {
            features = features.concat(shape.coordinates[p])
          }
        }
      } else {
        features.push(shape.coordinates[0])
      }
    }

    // 面数据和遮罩
    if (district.shape.type === 'MultiPolygon') {
      // eslint-disable-next-line guard-for-in,no-restricted-syntax
      for (const o in district.shape.coordinates) {
        outSideShape = outSideShape.concat(district.shape.coordinates[o])
        featuresPolygon = featuresPolygon.concat([
          district.shape.coordinates[o]
        ])
      }
    }
    // 遮罩
    map.getSource('mask-polygon').setData({
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          geometry: {
            type: 'MultiPolygon',
            coordinates: [outSideShape]
          }
        }
      ]
    })

    // 行政区划边界
    map.getSource('power-line').setData({
      type: 'FeatureCollection',
      features: [
        {
          type: 'Feature',
          geometry: {
            type: 'MultiLineString',
            coordinates: features
          }
        }
      ]
    })
  }

  /**
   * 计算像素偏移量后的经纬度
   * @param coordinate
   * @param pixelArray
   * @returns {*[]|*}
   */
  computedOffsetCoordinate(coordinate, pixelArray = [0, 0]) {
    if (!coordinate) {
      throw new Error('coordinate是必须的')
    }
    const { map } = this
    const pixel = map.project(coordinate)
    const offsetPixel = {
      x: pixel.x + pixelArray[0],
      y: pixel.y + pixelArray[1]
    }
    const result = map.unproject(offsetPixel)
    return [result.lng, result.lat]
  }
}
